/*                                                                      
 Copyright 2018 hzheng@gzhu.edu.cn              
                                                                         
 Licensed under the Apache License, Version 2.0 (the "License");         
 you may not use this file except in compliance with the License.        
 You may obtain a copy of the License at                                 
                                                                         
     http://www.apache.org/licenses/LICENSE-2.0                          
                                                                         
  Unless required by applicable law or agreed to in writing, software    
 distributed under the License is distributed on an "AS IS" BASIS,       
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and     
 limitations under the License.                                          
 */                                                                      
/*+***********************************************************
Filename: zh_core_v02.v
Description: a simple RISC-V core that execute add/sub and jump only.
Modification:
  2018.07.27 createion by Zheng Hui
  2018.08.20 i_pc[4:0] = pc_value[6:2];
  2019.03.23 add ram

************************************************************-*/

module zh_core_v02(
  input sys_clk,
  input rst_n,
  output [31:0] gpio1out,
  output [3:0] inspect,
  output [31:0] inspect2
);

wire core_clk;
wire [31:0] pc_offset;
wire pc_jump_flag;
wire [31:0] pc_value;

/*
assign inspect[0] = pc_value[0];
assign inspect[1] = core_clk;
assign inspect[2] = pc_jump_flag;
assign inspect[3] = alu_enable;
*/
assign inspect[0] = rf_rd_data[0];
//assign inspect[0] = alu_data_b[0];
assign inspect[1] = core_clk;
assign inspect[2] = rf_rdwen;
//assign inspect[2] = alu_add_flag;
assign inspect[3] = alu_enable;
assign inspect2 = pc_value;





wire [4:0] i_pc;
//assign  i_pc[4:0] = pc_value[4:0];
assign  i_pc[4:0] = pc_value[6:2];
wire [31:0] instruction;

    //provide instruction
    GW_ROM instruction_rom(
        .dout(instruction), //output [31:0] dout
        .clk(sys_clk), //input clk
        .oce(1), //input oce
        .ce(1), //input ce
        .reset(0), //input reset
        .wre(0), //input wre
        .ad(i_pc) //input [4:0] ad
    );

//data ram
wire [31:0] ram_dout;
wire [31:0] ram_din;
wire [9:0] ram_addr;
wire [3:0] ram_byte_en;
wire ram_wre;

    GW_SP data_ram(
        .dout(ram_dout), //output [31:0] dout
        .clk(sys_clk), //input clk
        .oce(1), //input oce
        .ce(1), //input ce
        .reset(0), //input reset
        .wre(ram_wre), //input wre
        .ad(ram_addr), //input [9:0] ad
        .din(ram_din), //input [31:0] din
        .byte_en(ram_byte_en) //input [3:0] byte_en
    );

    //ctrl module
  
  //to regfile
  wire [4:0] rf_rs1idx;
  wire [4:0] rf_rs2idx;
  wire  [31:0] rf_rs1data;
  wire  [31:0] rf_rs2data;
  wire [4:0] rf_rdidx;
  wire rf_rdwen;
  wire [31:0] rf_rd_data;

  //to alu
  wire[31:0] alu_data_a;
  wire[31:0] alu_data_b;
  wire alu_add_flag;  
  wire alu_sub_flag;
  wire alu_unsigned_flag;
  wire alu_enable;
  wire [31:0] alu_sum_value;

    //ctrl module
 /*
    zh_exec_ctrl_v02 m_zh_exec_ctrl(
        .sys_clk(sys_clk),
        .rst_n(rst_n),
        .core_clk(core_clk),

        .i_instr(instruction),
        .rf_rs1idx(rf_rs1idx),
        .rf_rs2idx(rf_rs2idx),
        .i_rf_rs1data(rf_rs1data),
        .i_rf_rs2data(rf_rs2data),
        .rf_rdidx(rf_rdidx),
        .rf_rdwen(rf_rdwen),
        .rf_rd_data(rf_rd_data),

        .alu_data_a(alu_data_a),
        .alu_data_b(alu_data_b),
        .alu_add_flag(alu_add_flag),
        .alu_sub_flag(alu_sub_flag),
        .alu_unsigned_flag(alu_unsigned_flag),
        .alu_enable(alu_enable),
        .i_alu_result(alu_sum_value),

        .pc_value(pc_value)
    );
 */
// /*
    zh_exec_ctrl_v03 m_zh_exec_ctrl(
        .sys_clk(sys_clk),
        .rst_n(rst_n),
        .core_clk(core_clk),

        .i_instr(instruction),
        .rf_rs1idx(rf_rs1idx),
        .rf_rs2idx(rf_rs2idx),
        .i_rf_rs1data(rf_rs1data),
        .i_rf_rs2data(rf_rs2data),
        .rf_rdidx(rf_rdidx),
        .rf_rdwen(rf_rdwen),
        .rf_rd_data(rf_rd_data),

        .alu_data_a(alu_data_a),
        .alu_data_b(alu_data_b),
        .alu_add_flag(alu_add_flag),
        .alu_sub_flag(alu_sub_flag),
        .alu_unsigned_flag(alu_unsigned_flag),
        .alu_enable(alu_enable),
        .i_alu_result(alu_sum_value),

        .pc_value(pc_value),

        .ram_addr(ram_addr),
        .ram_din(ram_din),
        .ram_dout(ram_dout),
        .ram_byte_en(ram_byte_en),
        .ram_wre(ram_wre)
    );
// */

    //register file
    zh_regfile_v01 m_zh_regfile(
        .rst_n(rst_n),
        .core_clk(core_clk),

        .i_rf_rs1idx(rf_rs1idx),
        .i_rf_rs2idx(rf_rs2idx),
        .rf_rs1data(rf_rs1data),
        .rf_rs2data(rf_rs2data),
        .i_rf_rdidx(rf_rdidx),
        .i_rf_rdwen(rf_rdwen),
        .i_rf_rd_data(rf_rd_data),
        .gpio1out(gpio1out)
    );

    //alu
    zh_exec_alu_v02 m_zh_exec_alu(
        .i_alu_data_a(alu_data_a),
        .i_alu_data_b(alu_data_b),
        .i_alu_unsigned_flag(alu_unsigned_flag),
        .i_alu_add_flag(alu_add_flag),
        .i_alu_sub_flag(alu_sub_flag),
        .i_alu_enable(alu_enable),
        .alu_result(alu_sum_value)
    );

endmodule


